package org.springblade.modules.restaurant.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.common.tool.CommonUtil;
import org.springblade.core.mp.base.TenantEntity;
import org.springblade.modules.restaurant.entity.*;
import org.springblade.modules.restaurant.enums.CommodityRecordStatusEnums;
import org.springblade.modules.restaurant.enums.TaskRecordStatusEnums;
import org.springblade.modules.restaurant.service.*;
import org.springblade.modules.restaurant.vo.PieSeriesVO;
import org.springblade.modules.restaurant.vo.SearchTimeVO;
import org.springblade.modules.system.entity.Dept;
import org.springblade.modules.system.entity.Dict;
import org.springblade.modules.system.service.IDeptService;
import org.springblade.modules.system.service.IDictService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author harry
 * @公众号 Harry技术
 */
@Service
@AllArgsConstructor
public class DashBoardServiceImpl implements IDashBoardService {

	private ITaskRecordService taskRecordService;
	private IOperatingIncomeService operatingIncomeService;
	private IAreaService areaService;
	private ICommodityRecordService commodityRecordService;
	private IPerformanceRatingService performanceRatingService;
	private IBusinessObjectivesService businessObjectivesService;
	private ICustomerSituationService customerSituationService;
	private IDictService dictService;
	private IUserSalaryDayService userSalaryDayService;
	private IUserSalaryService userSalaryService;
	private IDeptService deptService;


	@Override
	public List<Map<String, Object>> dataCounts(Long userId, String tenantId, String role) {

		List<Map<String, Object>> list = new ArrayList<>();

		long taskRecordCount = taskRecordService.lambdaQuery()
			.eq(TaskRecord::getStatus, TaskRecordStatusEnums.SUBMITTED.getCode())
			.count();
		list.add(convertDataCountsMap("taskRecord", "未审核任务", "el-icon-flag", "#409EFF", taskRecordCount));

		long commodityRecordCount = commodityRecordService.lambdaQuery()
			.eq(CommodityRecord::getStatus, CommodityRecordStatusEnums.WAIT_AUDIT.getStatus())
			.count();
		list.add(convertDataCountsMap("commodityRecord", "未审核采购单", "el-icon-list", "#67C23A", commodityRecordCount));

		long userCount = userSalaryService.lambdaQuery().eq(TenantEntity::getTenantId, tenantId).count();
		list.add(convertDataCountsMap("userCount", "员工数量", "el-icon-user", "rgb(50.8, 116.6, 184.5)", userCount));

		BusinessObjectives businessObjectives = businessObjectivesService.lambdaQuery()
			.eq(BusinessObjectives::getTenantId, tenantId)
			.eq(BusinessObjectives::getBusinessTime, DateUtil.format(new Date(), DatePattern.NORM_MONTH_PATTERN))
			.one();

		if (businessObjectives != null) {
			// 经营收入
			BigDecimal incomeAmount = businessObjectives.getIncomeAmount();
			// 总支出
			BigDecimal expendAmount = businessObjectives.getExpendAmount();
			// 营业净利
			BigDecimal netProfit = businessObjectives.getNetProfit();
			// 薪资支出
			BigDecimal salaryExpenses = businessObjectives.getSalaryExpenses();
			// 费用支出
			BigDecimal otherExpenses = businessObjectives.getOtherExpenses();
			// 预算支出
			BigDecimal fixedExpenses = businessObjectives.getFixedExpenses();
			// 采购支出
			BigDecimal procurementExpenses = businessObjectives.getProcurementExpenses();

			// 营业目标金额
			BigDecimal businessTargetAmount = businessObjectives.getBusinessTargetAmount();
			list.add(convertDataCountsMap("netProfit", "营业净利（当月）", "el-icon-wallet-filled", "#F56C6C", netProfit));
			list.add(convertDataCountsMap("totalIncome", "经营收入（当月）", "el-icon-credit-card", "#F56C6C", incomeAmount));
			list.add(convertDataCountsMap("totalExpense", "总支出（当月）", "el-icon-sell", "#E6A23C", expendAmount));
			list.add(convertDataCountsMap("procurementExpenses", "采购支出（当月）", "shopping-cart", "#409EFF", procurementExpenses));
			list.add(convertDataCountsMap("fixedExpenses", "预算支出（当月）", "el-icon-place", "rgb(50.8, 116.6, 184.5)", fixedExpenses));
			list.add(convertDataCountsMap("salaryExpenses", "薪资支出（当月）", "el-icon-wallet", "#F56C6C", salaryExpenses));
			list.add(convertDataCountsMap("otherExpenses", "费用支出（当月）", "el-icon-document", "#E6A23C", otherExpenses));

			if (userCount > 0) {
				// 获取截止到昨天的人效
				long ofDay = (DateUtil.dayOfMonth(DateUtil.date()) - 1) * userCount;
				BigDecimal personEfficiencyDay = BigDecimal.ZERO;
				if (ofDay > 0) {
					personEfficiencyDay = incomeAmount.divide(BigDecimal.valueOf(ofDay), 2, RoundingMode.HALF_UP);
				}
				list.add(convertDataCountsMap("personEfficiencyDay", "人效（平均）", "el-icon-odometer", "#F56C6C", personEfficiencyDay));

				BigDecimal personEfficiencyM = BigDecimal.ZERO;
				long day = CommonUtil.getDays(DateUtil.formatDate(DateUtil.date()), DatePattern.NORM_DATE_PATTERN) * userCount;
				if (day > 0) {
					personEfficiencyM = businessTargetAmount.divide(BigDecimal.valueOf(day), 2, RoundingMode.HALF_UP);
				}
				list.add(convertDataCountsMap("personEfficiencyM", "人效（目标）", "el-icon-odometer", "#E6A23C", personEfficiencyM));
			}
		}

		return list;
	}

	@Override
	public Map<String, Object> areaMonthsScores(Long userId, String tenantId, String role) {

		Map<String, Object> map = new HashMap<>(16);
		// 获取最近三个月的月份
		List<String> months = new ArrayList<>();
		for (int i = 0; i < 3; i++) {
			String month = DateUtil.format(DateUtil.offsetMonth(DateUtil.date(), -(2 - i)), DatePattern.NORM_MONTH_PATTERN);
			months.add(month);
		}
		map.put("categories", months);
		return areaScoresSeries(map, months, userId, tenantId, role);
	}

	@Override
	public Map<String, Object> dayIncomeExpenditureStatistics(Long userId, String tenantId, String role) {
		Map<String, Object> map = new HashMap<>(16);
		// 获取最近15天的日期
		List<String> days = new ArrayList<>();
		for (int i = 0; i < 15; i++) {
			String day = DateUtil.formatDate(DateUtil.offsetDay(DateUtil.date(), -(14 - i)));
			days.add(day);
		}
		map.put("categories", days);
		map.put("title", "收支统计（日）");

		return dayIncomeExpenditureSeries(map, days, tenantId);
	}

	@Override
	public Map<String, Object> monthIncomeExpenditureStatistics(Long userId, String tenantId, String role) {
		Map<String, Object> map = new HashMap<>(16);
		// 获取最近七个月的月份
		List<String> months = new ArrayList<>();
		for (int i = 0; i < 3; i++) {
			String month = DateUtil.format(DateUtil.offsetMonth(DateUtil.date(), -(2 - i)), DatePattern.NORM_MONTH_PATTERN);
			months.add(month);
		}
		map.put("categories", months);
		map.put("title", "收支统计（月）");

		return monthIncomeExpenditureSeries(map, months, tenantId);
	}

	@Override
	public Map<String, Object> taskStatistics(Long userId, String tenantId, String role) {

		Map<String, Object> map = new HashMap<>(16);
		// 获取最近七个月的月份
		List<String> months = new ArrayList<>();
		for (int i = 0; i < 3; i++) {
			String month = DateUtil.format(DateUtil.offsetMonth(DateUtil.date(), -(2 - i)), DatePattern.NORM_MONTH_PATTERN);
			months.add(month);
		}
		map.put("categories", months);

		return taskSeries(map, months, userId, role);
	}

	@Override
	public List<Map<String, Object>> todoListByMini(Long userId, String tenantId, String role) {

		List<Map<String, Object>> list = new ArrayList<>();

		long taskCount = taskRecordService.taskCount(userId, role);
		// 当天待办任务 | 当天任务总数
		long waitTaskCount = taskRecordService.waitTaskCount(userId, role);

		list.add(convertTodoListMapByMini("工作任务", "pushpin", waitTaskCount + " | " + taskCount, "/pages/usertask/usertask", true, "switchTab"));

		long commodityCount = 0;
		if (role.contains("admin")) {
			commodityCount = commodityRecordService.list(Wrappers.<CommodityRecord>lambdaQuery()
				.eq(CommodityRecord::getStatus, CommodityRecordStatusEnums.WAIT_AUDIT.getStatus())).size();
		}
		list.add(convertTodoListMapByMini("门店采购", "order", commodityCount, "/subpackage/commodity/commodity", true));

		boolean isCustomer = false;
		if (role.contains("admin")) {
			isCustomer = true;
		} else {
			// 如果当前用户是订台 、管理员角色，则显示客情资讯
			UserSalary user = userSalaryService.lambdaQuery().eq(UserSalary::getUserId, userId).one();
			if (user != null) {
				isCustomer = user.getIsBooker() == 1;
			}
		}
		long customerCount = customerSituationService.count(Wrappers.<CustomerSituation>lambdaQuery().eq(CustomerSituation::getWriteDate, DateUtil.formatDate(DateUtil.date())));
		// 总数
		long customerCountAll = customerSituationService.count();
		list.add(convertTodoListMapByMini("客情资讯", "account", customerCount + " | " + customerCountAll, "/subpackage/customer/customer", isCustomer));

		return list;
	}

	@Override
	public Map<String, Object> taskStatisticsByMini(Long userId, String tenantId, String role) {
		Map<String, Object> map = new HashMap<>(16);
		// 获取最近七个月的月份
		List<String> months = new ArrayList<>();
		List<String> monthsM = new ArrayList<>();
		for (int i = 0; i < 7; i++) {
			DateTime date = DateUtil.offsetMonth(DateUtil.date(), -(6 - i));
			String month = DateUtil.format(date, DatePattern.NORM_MONTH_PATTERN);
			String monthM = (DateUtil.month(date) + 1) + "月";
			months.add(month);
			monthsM.add(monthM);
		}
		map.put("categories", monthsM);

		return taskSeries(map, months, userId, role);
	}

	@Override
	public Map<String, Object> scoreStatisticsByMini(Long userId, String tenantId, String role) {
		Map<String, Object> map = new HashMap<>(16);
		// 获取最近七个月的月份
		List<String> months = new ArrayList<>();
		List<String> monthsM = new ArrayList<>();
		for (int i = 0; i < 7; i++) {
			DateTime date = DateUtil.offsetMonth(DateUtil.date(), -(6 - i));
			String month = DateUtil.format(date, DatePattern.NORM_MONTH_PATTERN);
			String monthM = (DateUtil.month(date) + 1) + "月";
			months.add(month);
			monthsM.add(monthM);
		}
		map.put("categories", monthsM);

		return areaScoresSeries(map, months, userId, tenantId, role);

	}

	@Override
	public Map<String, Object> dayIncomeExpenditureStatisticsByMini(Long userId, String tenantId, String role, SearchTimeVO searchTime) {
		Map<String, Object> map = new HashMap<>(16);

		String startTime = searchTime.getStartTime();
		String endTime = searchTime.getEndTime();

		// 获取最近7天的日期
		List<String> days = new ArrayList<>();
		List<String> daysD = new ArrayList<>();
		// 获取当前时间范围内的日期
		DateTime endTimeParse = DateUtil.parse(endTime, DatePattern.NORM_DATE_PATTERN);

		long countDay = DateUtil.between(DateUtil.parse(startTime, DatePattern.NORM_DATE_PATTERN), DateUtil.parse(endTime, DatePattern.NORM_DATE_PATTERN), DateUnit.DAY);
		for (long i = 0; i <= countDay; i++) {
			int offset = (int) -(countDay - i);
			String day = DateUtil.formatDate(DateUtil.offsetDay(endTimeParse, offset));
			String d = (DateUtil.dayOfMonth(DateUtil.offsetDay(endTimeParse, offset))) + "日";
			days.add(day);
			daysD.add(d);
		}
		map.put("categories", daysD);

		return dayIncomeExpenditureSeries(map, days, tenantId);
	}

	@Override
	public Map<String, Object> monthIncomeExpenditureStatisticsByMini(Long userId, String tenantId, String role) {
		Map<String, Object> map = new HashMap<>(16);
		// 获取最近七个月的月份
		List<String> months = new ArrayList<>();
		List<String> monthsM = new ArrayList<>();
		for (int i = 0; i < 7; i++) {
			DateTime date = DateUtil.offsetMonth(DateUtil.date(), -(6 - i));
			String month = DateUtil.format(date, DatePattern.NORM_MONTH_PATTERN);
			String monthM = (DateUtil.month(date) + 1) + "月";
			months.add(month);
			monthsM.add(monthM);
		}
		map.put("categories", monthsM);

		return monthIncomeExpenditureSeries(map, months, tenantId);
	}

	@Override
	public Map<String, Object> attendanceStatisticsByMini(Long userId, String tenantId, String role, SearchTimeVO searchTime) {
		Map<String, Object> map = new HashMap<>(16);

		String startTime = searchTime.getStartTime();
		String endTime = searchTime.getEndTime();

		// 获取最近7天的日期
		List<String> days = new ArrayList<>();
		List<String> daysD = new ArrayList<>();
		// 获取当前时间范围内的日期
		DateTime endTimeParse = DateUtil.parse(endTime, DatePattern.NORM_DATE_PATTERN);

		long countDay = DateUtil.between(DateUtil.parse(startTime, DatePattern.NORM_DATE_PATTERN), DateUtil.parse(endTime, DatePattern.NORM_DATE_PATTERN), DateUnit.DAY);
		for (long i = 0; i <= countDay; i++) {
			int offset = (int) -(countDay - i);
			String day = DateUtil.formatDate(DateUtil.offsetDay(endTimeParse, offset));
			String d = (DateUtil.dayOfMonth(DateUtil.offsetDay(endTimeParse, offset))) + "日";
			days.add(day);
			daysD.add(d);
		}
		map.put("categories", daysD);

		List<Map<String, Object>> attendanceData = new ArrayList<>();
		List<Dict> namesList = dictService.getList("attendance_type");
		namesList.forEach(dict -> {
			Map<String, Object> nameMap = new HashMap<>(16);
			nameMap.put("name", dict.getDictValue());

			List<UserSalaryDay> userSalaryDays = userSalaryDayService.lambdaQuery()
				.between(UserSalaryDay::getTime, startTime, endTime)
				.eq(UserSalaryDay::getType, dict.getDictKey())
				.list();

			// 根据时间分组
			Map<String, Integer> countMap = userSalaryDays.stream().collect(Collectors.toMap(UserSalaryDay::getTime, userSalaryDay -> 1, Integer::sum));
			List<Integer> count = new ArrayList<>();
			days.forEach(day -> {
				count.add(countMap.getOrDefault(day, 0));
				nameMap.put("data", count);
			});
			attendanceData.add(nameMap);
		});
		map.put("series", attendanceData);
		return map;
	}

	@Override
	public Map<String, Object> attendanceStatistics(Long userId, String tenantId, String role) {
		Map<String, Object> map = new HashMap<>(16);
		// 获取最近15天的日期
		List<String> days = new ArrayList<>();
		for (int i = 0; i < 15; i++) {
			String day = DateUtil.formatDate(DateUtil.offsetDay(DateUtil.date(), -(14 - i)));
			days.add(day);
		}
		map.put("categories", days);
		map.put("title", "考勤统计（日）");

		List<Map<String, Object>> attendanceData = new ArrayList<>();
		List<Dict> namesList = dictService.getList("attendance_type");
		namesList.forEach(dict -> {
			Map<String, Object> nameMap = new HashMap<>(16);
			nameMap.put("name", dict.getDictValue());

			DateTime now = DateUtil.date();
			// 获取开始时间  yyyy-MM-dd
			String startTime = DateUtil.formatDate(DateUtil.offsetDay(now, -14));
			// 获取当前时间 yyyy-MM-dd
			String endTime = DateUtil.formatDate(DateUtil.date());

			List<UserSalaryDay> userSalaryDays = userSalaryDayService.lambdaQuery()
				.between(UserSalaryDay::getTime, startTime, endTime)
				.eq(UserSalaryDay::getType, dict.getDictKey())
				.list();

			// 根据时间分组
			Map<String, Integer> countMap = userSalaryDays.stream().collect(Collectors.toMap(UserSalaryDay::getTime, userSalaryDay -> 1, Integer::sum));
			List<Integer> count = new ArrayList<>();
			days.forEach(day -> {
				count.add(countMap.getOrDefault(day, 0));
				nameMap.put("data", count);
			});
			attendanceData.add(nameMap);
		});
		map.put("series", attendanceData);
		return map;
	}

	@Override
	public Map<String, Object> todayIncomeExpenditureStatistics(Long userId, String tenantId, String role, String day) {
		Map<String, Object> map = new HashMap<>(16);
		List<PieSeriesVO> items = new ArrayList<>();
		OperatingIncome income = operatingIncomeService.lambdaQuery().eq(OperatingIncome::getOperatingTime, day)
			.eq(OperatingIncome::getTenantId, tenantId).one();

		List<Map<String, Object>> data = new ArrayList<>();
		if (income != null) {
			// 经营收入
			BigDecimal incomeAmount = income.getTotalIncome();
			// 总支出
			BigDecimal expendAmount = income.getExpendAmount();
			// 营业毛利
			BigDecimal profitAmount = income.getProfitAmount();
			// 薪资支出
			BigDecimal salaryExpenses = income.getSalaryExpenses();
			// 费用支出
			BigDecimal otherExpenses = income.getOtherExpenses();
			// 预算支出
			BigDecimal fixedExpenses = income.getFixedExpenses();
			// 采购支出
			BigDecimal procurementExpenses = income.getProcurementExpenses();
			// 营业净利
			BigDecimal netProfit = income.getNetProfit();

			items.add(new PieSeriesVO("营业毛利", profitAmount));
			items.add(new PieSeriesVO("营业净利", netProfit));
			items.add(new PieSeriesVO("经营收入", incomeAmount));
			items.add(new PieSeriesVO("总支出", expendAmount));
			items.add(new PieSeriesVO("薪资支出", salaryExpenses));
			items.add(new PieSeriesVO("费用支出", otherExpenses));
			items.add(new PieSeriesVO("预算支出", fixedExpenses));
			items.add(new PieSeriesVO("采购支出", procurementExpenses));

		}
		Map<String, Object> dataMap = new HashMap<>(16);
		dataMap.put("data", items);
		data.add(dataMap);
		map.put("series", data);
		return map;
	}

	@Override
	public List<Map<String, Object>> deptUserStatistics(Long userId, String tenantId, String role) {
		List<Map<String, Object>> list = new ArrayList<>();

		String toDay = DateUtil.today();
		List<UserSalaryDay> userSalaries = userSalaryDayService.lambdaQuery()
			.eq(UserSalaryDay::getTenantId, tenantId)
			.eq(UserSalaryDay::getTime, toDay)
			.list();
		// 根据部门分组
		Map<Long, List<UserSalaryDay>> userSalaryMap = userSalaries.stream().collect(Collectors.groupingBy(UserSalaryDay::getCreateDept));
		userSalaryMap.forEach((createDept, value) -> {
			Dept dept = deptService.getById(createDept);
			if (dept != null) {
				String deptName = dept.getDeptName();
				Long parentId = dept.getParentId();
				if (parentId == 0) {
					deptName = "公司部门";
				}
				list.add(convertTodoListMapByMini(deptName, "", (long) value.size(), "/subpackage/attendance/attendance?createDept=" + createDept, true));
			}
		});
		return list;
	}

	@Override
	public Map<String, Object> dailyHumanEfficiency(Long userId, String tenantId, String role) {
		Map<String, Object> map = new HashMap<>(16);
		// 获取最近15天的日期
		List<String> days = new ArrayList<>();
		for (int i = 0; i < 15; i++) {
			String day = DateUtil.formatDate(DateUtil.offsetDay(DateUtil.date(), -(14 - i)));
			days.add(day);
		}
		map.put("categories", days);
		map.put("title", "日均人效");

		List<Map<String, Object>> maps = new ArrayList<>();
		List<OperatingIncome> operatingIncomes = operatingIncomeService.lambdaQuery()
			.in(OperatingIncome::getOperatingTime, days)
			.eq(OperatingIncome::getTenantId, tenantId)
			.list();

		Map<String, Object> mapData = new HashMap<>(16);
		Map<String, Object> mapTargetData = new HashMap<>(16);
		Map<String, Object> mapUserData = new HashMap<>(16);
		List<BigDecimal> datas = new ArrayList<>();
		// 目标人效
		List<BigDecimal> targets = new ArrayList<>();
		List<Long> users = new ArrayList<>();
		for (String day : days) {
			BigDecimal targetData = BigDecimal.ZERO;
			BigDecimal data = BigDecimal.ZERO;
			// 当天参与考勤人数
			long userCount = userSalaryDayService.lambdaQuery()
				.eq(UserSalaryDay::getTime, day)
				.eq(TenantEntity::getTenantId, tenantId).count();
			users.add(userCount);
			if (userCount > 0) {
				// 目标人效
				BusinessObjectives businessObjectives = businessObjectivesService.lambdaQuery()
					.eq(BusinessObjectives::getTenantId, tenantId)
					.eq(BusinessObjectives::getBusinessTime, DateUtil.format(DateUtil.parse(day), DatePattern.NORM_MONTH_PATTERN))
					.one();
				if (businessObjectives != null) {
					int dayCount = CommonUtil.getDays(day, DatePattern.NORM_DATE_PATTERN);
					targetData = businessObjectives.getBusinessTargetAmount().divide(new BigDecimal(userCount * dayCount), 2, RoundingMode.HALF_UP);
				}
				for (OperatingIncome operatingIncome : operatingIncomes) {
					if (operatingIncome.getOperatingTime().equals(day)) {
						BigDecimal totalIncome = operatingIncome.getTotalIncome();
						data = totalIncome.divide(new BigDecimal(userCount), 2, RoundingMode.HALF_UP);
						break;
					}
				}
				datas.add(data);
				targets.add(targetData);
				mapData.put("data", datas);
			}
		}
		mapData.put("name", "人效");
		maps.add(mapData);

		mapTargetData.put("name", "目标人效");
		mapTargetData.put("data", targets);
		maps.add(mapTargetData);


		mapUserData.put("name", "员工数");
		mapUserData.put("data", users);
		mapUserData.put("type", "bar");

		maps.add(mapUserData);
		map.put("series", maps);

		return map;
	}

	@Override
	public Map<String, Object> monthlyHumanEfficiency(Long userId, String tenantId, String role) {
		Map<String, Object> map = new HashMap<>(16);
		// 获取最近三个月的月份
		List<String> months = new ArrayList<>();
		for (int i = 0; i < 3; i++) {
			String month = DateUtil.format(DateUtil.offsetMonth(DateUtil.date(), -(2 - i)), DatePattern.NORM_MONTH_PATTERN);
			months.add(month);
		}
		map.put("categories", months);
		map.put("title", "月均人效");

		List<Map<String, Object>> maps = new ArrayList<>();
		Map<String, Object> mapData = new HashMap<>(16);
		Map<String, Object> mapTargetData = new HashMap<>(16);
		Map<String, Object> mapUserData = new HashMap<>(16);
		List<BigDecimal> datas = new ArrayList<>();
		// 目标人效
		List<BigDecimal> targets = new ArrayList<>();
		List<Long> users = new ArrayList<>();
		for (String month : months) {
			BigDecimal targetData = BigDecimal.ZERO;
			BigDecimal data = BigDecimal.ZERO;
			// 当月参与考勤人数
			long userCount = userSalaryDayService.lambdaQuery()
				.eq(UserSalaryDay::getTime, DateUtil.formatDate(DateUtil.parse(month, DatePattern.NORM_MONTH_PATTERN)))
				.eq(TenantEntity::getTenantId, tenantId).count();
			users.add(userCount);
			if (userCount > 0) {
				// 目标人效
				BusinessObjectives businessObjectives = businessObjectivesService.lambdaQuery().eq(BusinessObjectives::getTenantId, tenantId).eq(BusinessObjectives::getBusinessTime, month).one();
				if (businessObjectives != null) {
					targetData = businessObjectives.getBusinessTargetAmount().divide(new BigDecimal(userCount), 2, RoundingMode.HALF_UP);
					data = businessObjectives.getIncomeAmount().divide(new BigDecimal(userCount), 2, RoundingMode.HALF_UP);
				}
			}
			datas.add(data);
			targets.add(targetData);
			mapData.put("data", datas);
		}
		mapData.put("name", "人效");
		maps.add(mapData);

		mapTargetData.put("name", "目标人效");
		mapTargetData.put("data", targets);
		maps.add(mapTargetData);


		mapUserData.put("name", "员工数");
		mapUserData.put("data", users);
		mapUserData.put("type", "bar");

		maps.add(mapUserData);
		map.put("series", maps);

		return map;
	}

	private Map<String, Object> areaScoresSeries(Map<String, Object> map, List<String> months, Long userId, String tenantId, String role) {

		List<Map<String, Object>> areaScores = new ArrayList<>();

		if (!role.contains("employee")) {
			map.put("title", "区域评分（月）");
			// 获取每个区域每个月评分
			List<Area> areas = areaService.lambdaQuery().eq(Area::getType, 1).list();
			areas.forEach(area -> {
				// 根据areaId 获取子区域
				Map<String, Object> areaMap = new HashMap<>(16);
				areaMap.put("name", area.getAreaName());
				List<BigDecimal> scores = new ArrayList<>();
				months.forEach(month -> {
					PerformanceRating performanceRating = performanceRatingService.lambdaQuery()
						.eq(PerformanceRating::getAreaId, area.getId())
						.eq(PerformanceRating::getMonth, month).one();
					BigDecimal score = performanceRating == null ? BigDecimal.ZERO : performanceRating.getScore();
					scores.add(score);
					areaMap.put("data", scores);
				});
				areaScores.add(areaMap);
			});
			map.put("series", areaScores);
		} else {
			map.put("title", "员工评分（月）");
			Map<String, Object> areaMap = new HashMap<>(16);
			areaMap.put("name", "综合评分");
			List<BigDecimal> scores = new ArrayList<>();
			months.forEach(month -> {
				PerformanceRating performanceRating = performanceRatingService.lambdaQuery()
					.eq(PerformanceRating::getUserId, userId)
					.eq(PerformanceRating::getMonth, month).one();
				BigDecimal score = performanceRating == null ? BigDecimal.ZERO : performanceRating.getScore();
				scores.add(score);
				areaMap.put("data", scores);
			});
			areaScores.add(areaMap);
			map.put("series", areaScores);
		}
		return map;
	}


	private Map<String, Object> taskSeries(Map<String, Object> map, List<String> months, Long userId, String role) {

		map.put("title", "任务统计（月）");
		List<Map<String, Object>> taskCounts = new ArrayList<>();
		Arrays.stream(TaskRecordStatusEnums.values()).forEach(taskRecordStatusEnums -> {
			Map<String, Object> nameMap = new HashMap<>(16);
			nameMap.put("name", taskRecordStatusEnums.getDesc());
			List<Long> amounts = new ArrayList<>();
			months.forEach(month -> {
				String startTime = DateUtil.formatDate(DateUtil.beginOfMonth(DateUtil.parse(month, "yyyy-MM")));
				String endTime = DateUtil.formatDate(DateUtil.endOfMonth(DateUtil.parse(month, "yyyy-MM")));
				long count;
				if (!role.contains("employee")) {
					count = taskRecordService.lambdaQuery()
						.eq(TaskRecord::getStatus, taskRecordStatusEnums.getCode())
						.ge(TaskRecord::getTaskTime, startTime)
						.le(TaskRecord::getTaskTime, endTime)
						.count();
				} else {
					count = taskRecordService.lambdaQuery()
						.eq(TaskRecord::getStatus, taskRecordStatusEnums.getCode())
						.ge(TaskRecord::getTaskTime, startTime)
						.le(TaskRecord::getTaskTime, endTime)
						.eq(TaskRecord::getUserId, userId)
						.count();
				}
				amounts.add(count);
				nameMap.put("data", amounts);
			});
			taskCounts.add(nameMap);
		});

		map.put("series", taskCounts);
		return map;
	}

	private Map<String, Object> dayIncomeExpenditureSeries(Map<String, Object> map, List<String> days, String tenantId) {
		List<Map<String, Object>> dayIncomeExpenditureData = new ArrayList<>();
		List<String> names = new ArrayList<>();
		names.add("营业毛利");
		names.add("营业净利");
		names.add("经营收入");
		names.add("总支出");
		names.add("薪资支出");
		names.add("费用支出");
		names.add("预算支出");
		names.add("采购支出");

		names.forEach(name -> {
			Map<String, Object> nameMap = new HashMap<>(16);
			nameMap.put("name", name);
			List<BigDecimal> amounts = new ArrayList<>();

			days.forEach(day -> {
				OperatingIncome income = operatingIncomeService.lambdaQuery().eq(OperatingIncome::getOperatingTime, day)
					.eq(OperatingIncome::getTenantId, tenantId).one();
				if (income != null) {
					// 经营收入
					BigDecimal incomeAmount = income.getTotalIncome();
					// 总支出
					BigDecimal expendAmount = income.getExpendAmount();
					// 营业毛利
					BigDecimal profitAmount = income.getProfitAmount();
					// 薪资支出
					BigDecimal salaryExpenses = income.getSalaryExpenses();
					// 费用支出
					BigDecimal otherExpenses = income.getOtherExpenses();
					// 预算支出
					BigDecimal fixedExpenses = income.getFixedExpenses();
					// 采购支出
					BigDecimal procurementExpenses = income.getProcurementExpenses();
					// 营业净利
					BigDecimal netProfit = income.getNetProfit();

					if (name.equals("经营收入")) {
						amounts.add(incomeAmount);
					}
					if (name.equals("总支出")) {
						amounts.add(expendAmount);
					}
					if (name.equals("营业毛利")) {
						amounts.add(profitAmount);
					}
					if (name.equals("薪资支出")) {
						amounts.add(salaryExpenses);
					}
					if (name.equals("费用支出")) {
						amounts.add(otherExpenses);
					}
					if (name.equals("预算支出")) {
						amounts.add(fixedExpenses);
					}
					if (name.equals("采购支出")) {
						amounts.add(procurementExpenses);
					}
					if (name.equals("营业净利")) {
						amounts.add(netProfit);
					}
					nameMap.put("data", amounts);
				}

			});
			dayIncomeExpenditureData.add(nameMap);
		});
		map.put("series", dayIncomeExpenditureData);
		return map;
	}

	private Map<String, Object> monthIncomeExpenditureSeries(Map<String, Object> map, List<String> months, String tenantId) {
		List<Map<String, Object>> monthIncomeExpenditureData = new ArrayList<>();
		List<String> names = new ArrayList<>();
		names.add("营业毛利");
		names.add("营业净利");
		names.add("经营收入");
		names.add("总支出");
		names.add("目标收入");
		names.add("目标利润");
		names.forEach(name -> {
			Map<String, Object> nameMap = new HashMap<>(16);
			nameMap.put("name", name);
			List<BigDecimal> amounts = new ArrayList<>();
			months.forEach(month -> {
				BusinessObjectives businessObjectives = businessObjectivesService.lambdaQuery()
					.eq(BusinessObjectives::getTenantId, tenantId)
					.eq(BusinessObjectives::getBusinessTime, month).one();
				if (businessObjectives != null) {
					switch (name) {
						case "经营收入":
							amounts.add(businessObjectives.getIncomeAmount());
							break;
						case "总支出":
							amounts.add(businessObjectives.getExpendAmount());
							break;
						case "营业毛利":
							amounts.add(businessObjectives.getProfitAmount());
							break;
						case "目标收入":
							amounts.add(businessObjectives.getBusinessTargetAmount());
							break;
						case "目标利润":
							amounts.add(businessObjectives.getProfitTargetAmount());
							break;
						case "营业净利":
							amounts.add(businessObjectives.getNetProfit());
							break;
						default:
							break;
					}
				} else {
					amounts.add(BigDecimal.ZERO);
				}
				nameMap.put("data", amounts);
			});
			monthIncomeExpenditureData.add(nameMap);
		});
		map.put("series", monthIncomeExpenditureData);
		return map;
	}

	private Map<String, Object> convertDataCountsMap(String key, String title, String icon, String color, Object count) {
		Map<String, Object> map = new HashMap<>(16);
		map.put("key", key);
		map.put("title", title);
		map.put("icon", icon);
		map.put("color", color);
		map.put("count", count);
		return map;
	}

	/**
	 * @param title       标题
	 * @param icon        图标
	 * @param count       数量
	 * @param url         路由
	 * @param isAllowJump 是否允许跳转
	 * @param linkTyp     跳转类型 默认：navigateTo switchTab
	 * @return
	 */
	private Map<String, Object> convertTodoListMapByMini(String title, String icon, Object count, String url, Boolean isAllowJump, String linkTyp) {
		Map<String, Object> map = new HashMap<>(16);
		map.put("title", title);
		map.put("icon", icon);
		map.put("count", count);
		map.put("url", url);
		map.put("isAllowJump", isAllowJump);
		map.put("linkTyp", linkTyp);
		return map;
	}

	private Map<String, Object> convertTodoListMapByMini(String title, String icon, Object count, String url, Boolean isAllowJump) {
		return convertTodoListMapByMini(title, icon, count, url, isAllowJump, "navigateTo");
	}

}
